﻿using log4net;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace DocumentMerge
{
    public partial class Form1 : Form
    {
        #region 定义属性字段
        // Log日志
        private readonly static ILog log = LogManager.GetLogger(typeof(Form1));

        /*
        OpenFileDialog gpsFileDialog = null;    // gps文件读取对话框
        OpenFileDialog testFileDialog = null;   // 路测文件读取对话框
        */

        // 路测文件中的重要信息
        struct Road_test
        {
            public DateTime dateTime;           // 时间
            public int RSSI;                    // 信号强度(1秒以内的平均值)
            public double SNR;                  // 信噪比(1秒以内的平均值)
            public double BLER0;                   // 通道0LDPC块错误(上一次和这一次之间的差值,取第一次)
            public double BLER1;                   // 通道1
            public double BLER2;                   // 通道2
        }

        // GPS文件中的重要信息
        struct GPS_info
        {
            public DateTime dateTime;           // 时间
            public string gpsPositionState;     // GPS定位状态:A-有效定位，V-无效定位
            public double gpsLongitude;         // GPS经度
            public double gpsLatitude;          // GPS维度
            public double gpsSpeed;             // GPS速度
        }

        // 线程阻塞的路测信息集合，容量为10
        BlockingCollection<Road_test> blockingCollectionRoadTest = new BlockingCollection<Road_test>(10);
        // 线程阻塞的GPS信息集合，容量为10
        BlockingCollection<GPS_info> blockingCollectionGpsInfo = new BlockingCollection<GPS_info>(10);
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            test();
        }

        /// <summary>
        /// 浏览GPS文本文件位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_gps_Click(object sender, EventArgs e)
        {
            /*
            gpsFileDialog = new OpenFileDialog();
            gpsFileDialog.InitialDirectory = "C:\\";
            gpsFileDialog.Filter = "文本文件|*.txt|All File|*.*";
            gpsFileDialog.FilterIndex = 0;
            gpsFileDialog.RestoreDirectory = true;
            if (gpsFileDialog.ShowDialog() == DialogResult.OK)
            {
                textBox_gps.Text = gpsFileDialog.FileName;
            }
            */
            // ************************************************
            // 浏览文件夹下的所有.txt文件
            // ************************************************
            // 获取到文件夹名称
            FolderBrowserDialog gps_folder = new FolderBrowserDialog();
            if (gps_folder.ShowDialog() == DialogResult.OK)
            {
                textBox_gps.Text = gps_folder.SelectedPath;
            }
        }

        /// <summary>
        /// 浏览路测文件路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_test_Click(object sender, EventArgs e)
        {
            /*
            testFileDialog = new OpenFileDialog();
            testFileDialog.InitialDirectory = "C:\\";
            testFileDialog.Filter = "文本文件|*.txt|All File|*.*";
            testFileDialog.FilterIndex = 0;
            testFileDialog.RestoreDirectory = true;
            if (testFileDialog.ShowDialog() == DialogResult.OK)
            {
                textBox_test.Text = testFileDialog.FileName;
            }
            */
            FolderBrowserDialog road_folder = new FolderBrowserDialog();
            if (road_folder.ShowDialog() == DialogResult.OK)
            {
                textBox_test.Text = road_folder.SelectedPath;
            }
        }

        /// <summary>
        /// 开始合并
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_start_Click(object sender, EventArgs e)
        {
            // *************************************************
            // 合并文件
            // *************************************************
            // 首先检测出文件是否存在
            if (String.IsNullOrEmpty(textBox_gps.Text))
            {
                MessageBox.Show("请选择需要的gps文件所在文件夹!");
                return;
            }
            else if (String.IsNullOrEmpty(textBox_test.Text))
            {
                MessageBox.Show("请选择需要的路测文件所在文件夹!");
                return;
            }
            try
            {
                // **************************************
                // 后台耗时处理
                // **************************************
                BackgroundWorker backgroundWorker = new BackgroundWorker();
                // 耗时操作
                backgroundWorker.DoWork += ((object os, DoWorkEventArgs de) =>
                {
                    // *************************************************
                    // 先合并GPS文件
                    // *************************************************
                    // 写入到的GPS临时文件
                    string sGPSTmpFile = @"tmpGps.txt";
                    // 存在删除
                    if (File.Exists(sGPSTmpFile))
                    {
                        File.Delete(sGPSTmpFile);
                    }
                    // 不存在创建
                    if (!File.Exists(sGPSTmpFile))
                    {
                        FileStream fs;
                        fs = File.Create(sGPSTmpFile);
                        fs.Close();
                    }
                    // 遍历GPS文件夹下的所有txt文件
                    foreach (string _gpsfilename in Directory.GetFiles($"{textBox_gps.Text}", "*.txt", SearchOption.AllDirectories))
                    {
                        // 一次把一个文件读取完毕
                        /*
                        using (StreamReader tempReader = new StreamReader(_gpsfilename, Encoding.GetEncoding("gb2312")))
                        {
                            string str = tempReader.ReadToEnd();
                            // 写入文件
                            using (StreamWriter sw = new StreamWriter(sGPSTmpFile, true))
                            {
                                // 开始写入
                                sw.Write(str);
                                // 清空缓冲区
                                sw.Flush();
                            }
                        }
                        */
                        // 读取一个文件中的内容
                        StreamReader tempReader = new StreamReader(_gpsfilename, Encoding.GetEncoding("gb2312"));
                        // 一行一行的读取
                        string str = tempReader.ReadLine();
                        while(str != null)
                        {
                            // 分割数据
                            string[] array = str.Split(',');
                            if (array[1] != "$GPRMC") // 直到读取到第一个正确数据
                            {
                                str = tempReader.ReadLine();
                            }
                            else if (array[4] == "")
                            {
                                str = tempReader.ReadLine();
                            }
                            else
                            {
                                break;
                            }
                        }
                        string str2 = tempReader.ReadLine();
                        while (str2 != null)
                        {
                            // 分割数据
                            string[] array = str2.Split(',');
                            if (array[1] != "$GPRMC")
                            {
                                str2 = tempReader.ReadLine();
                                continue;
                            }
                            else if (array[4] == "")
                            {
                                str2 = tempReader.ReadLine();
                                continue;
                            }
                            string tempstr = Comparer_time(str, str2);
                            // 写入到文件当中
                            using (StreamWriter sw = new StreamWriter(sGPSTmpFile, true))
                            {
                                // 开始写入
                                sw.WriteLine(tempstr);
                                // 清空缓冲区
                                sw.Flush();
                            }
                            str = str2;
                            // 读取下一行
                            str2 = tempReader.ReadLine();
                        }
                        tempReader.Close();
                    }
                    log.Info("所有GPS文件合并到tmpGps.txt文件中");
                    // ************************************************
                    // 再合并路测文件
                    // ************************************************
                    // 写入到的路测临时文件
                    string sRoadTmpFile = @"tmpRoad.txt";
                    // 存在删除
                    if (File.Exists(sRoadTmpFile))
                    {
                        File.Delete(sRoadTmpFile);
                    }
                    // 不存在创建
                    if (!File.Exists(sRoadTmpFile))
                    {
                        FileStream fs;
                        fs = File.Create(sRoadTmpFile);
                        fs.Close();
                    }
                    // 遍历路测文件夹下的所有txt文件
                    foreach (string _testfilename in Directory.GetFiles($"{textBox_test.Text}", "*.txt", SearchOption.AllDirectories))
                    {
                        // 一次读取完一个文件
                        using (StreamReader sr = new StreamReader(_testfilename, Encoding.GetEncoding("gb2312")))
                        {
                            // 跳过第一行
                            sr.ReadLine();
                            string str = sr.ReadToEnd();
                            // 写入到文件当中
                            using (StreamWriter sw = new StreamWriter(sRoadTmpFile, true))
                            {
                                // 开始写入
                                sw.Write(str);
                                // 清空缓存区
                                sw.Flush();
                            }
                        }
                        /*
                        using (StreamReader sr = new StreamReader(_testfilename, Encoding.GetEncoding("gb2312")))
                        {
                            // 跳过第一行
                            sr.ReadLine();
                            // 读取下一行
                            string str = sr.ReadLine();
                            while (str != null)
                            {
                                // 写入到文件当中
                                using (StreamWriter sw = new StreamWriter(sRoadTmpFile, true))
                                {
                                    // 开始写入
                                    sw.WriteLine(str);
                                    // 清空缓存区
                                    sw.Flush();
                                }
                                str = sr.ReadLine();
                            }
                        }
                        */
                    }
                    log.Info("所有路测文件合并到tmpRoad.txt文件中");
                });
                // 后台耗时操作完成时处理
                backgroundWorker.RunWorkerCompleted += ((object os, RunWorkerCompletedEventArgs ex) =>
                {
                    MessageBox.Show("所有的路测文件合并到了tmpRoad.txt中!!\n所有的GPS文件合并到了tmpGps.txt文件中!!");
                    // 统计周期
                    int period = Convert.ToInt32(textBox_period.Text);
                    // 任务1处理路测文件中的数据
                    Task task1 = Task.Factory.StartNew(() => {
                        int flag = 0;
                        Road_test road_Test = new Road_test
                        {
                            dateTime = new DateTime(),
                            RSSI = 0,
                            SNR = 0,
                            BLER0 = 0,
                            BLER1 = 0,
                            BLER2 = 0
                        };
                        DateTime temp = new DateTime();             // 保存临时的时间戳对比
                        int tempbler0count = 0;                     // 临时保存这一秒的BLER0总数的值
                        int tempbler1count = 0;                     // 临时保存这一秒的BLER1总数的值
                        int tempbler2count = 0;                     // 临时保存这一秒的BLER2总数的值
                        List<int> arrayRSSI = new List<int>();      // 存储RSSI的数组
                        List<float> arraySNR = new List<float>();   // 存储SNR的数组
                        List<int> arrayBLER0 = new List<int>();     // 存储1S以内的BLER0
                        List<int> arrayBLER1 = new List<int>();
                        List<int> arrayBLER2 = new List<int>();
                        List<int> arrayBLER0Count = new List<int>();
                        List<int> arrayBLER1Count = new List<int>();
                        List<int> arrayBLER2Count = new List<int>();

                        // roadtest文件中的数据转换为流
                        StreamReader stroad = new StreamReader(@"tmpRoad.txt", Encoding.GetEncoding("gb2312"));
                        // 去掉第一行
                        stroad.ReadLine();
                        string str2 = stroad.ReadLine();
                        // 失锁标记
                        bool losinglock0 = false; // 通道0失锁标记
                        bool losinglock1 = false; // 通道1失锁标记
                        bool losinglock2 = false; // 通道2失锁标记
                        while (str2 != null)
                        {
                            Console.WriteLine($"\n路测文件一行数据:{str2}");                // 打印读取到的数据
                            str2 = System.Text.RegularExpressions.Regex.Replace(str2, @"\s+", ",").Trim(); // 将字符串中的空格替换为','
                            if (str2 == "")
                            {
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            string[] t = str2.Split(',');           // 以','分割字符串
                            // 去掉时间格式字符串后三位代表毫秒的数据
                            string time = t[0].Substring(0, t[0].Length - 3);
                            // 带毫秒的时间戳
                            // string time = t[0];
                            // 转化为时间DateTime
                            // 带毫秒格式
                            DateTime theDate = DateTime.ParseExact(t[0], "yyyyMMddHHmmssfff", CultureInfo.CurrentCulture);
                            // 不带毫秒的日期格式
                            DateTime theDateSave = DateTime.ParseExact(time, "yyyyMMddHHmmss", CultureInfo.CurrentCulture);
                            int rssi = 0;
                            float snr = 0.0f;
                            int b = 0;
                            int bl = 0;
                            int bler0 = 0;
                            int bler1 = 0;
                            int bler2 = 0;
                            int bler0count = 0;
                            int bler1count = 0;
                            int bler2count = 0;
                            // RSSI
                            if (!int.TryParse(t[3], out rssi))
                            {
                                log.Error($"原数据'{t[3]}'转换为RSSI出错,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // SNR
                            if (!float.TryParse(t[4], out snr))
                            {
                                log.Error($"原数据'{t[4]}'转换为SNR出错，时间{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BER
                            if (!int.TryParse(t[5], out b))
                            {
                                log.Error($"原数据'{t[5]}'转换为BER失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER
                            if (!int.TryParse(t[6], out bl))
                            {
                                log.Error($"原数据'{t[6]}'转换为BLER失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER0Count
                            if (!int.TryParse(t[31], out bler0count))
                            {
                                log.Error($"原数据'{t[31]}'转换为通道0的LDPC块总数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER0
                            if (!int.TryParse(t[32], out bler0))
                            {
                                log.Error($"原数据'{t[32]}'转换为通道0的LDPC错误块数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER1Count
                            if (!int.TryParse(t[33], out bler1count))
                            {
                                log.Error($"原数据'{t[33]}'转换为通道1的LDPC块总数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER1
                            if (!int.TryParse(t[34], out bler1))
                            {
                                log.Error($"原数据'{t[34]}'转换为通道1的LDPC错误块数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER2Count
                            if (!int.TryParse(t[35], out bler2count))
                            {
                                log.Error($"原数据'{t[35]}'转换为通道2的LDPC块总数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            // BLER2
                            if (!int.TryParse(t[36], out bler2))
                            {
                                log.Error($"原数据'{t[36]}'转换为通道2的LDPC错误块数失败,时间:{t[0]}");
                                str2 = stroad.ReadLine();
                                continue;
                            }
                            object obj = new object();
                            // 保存第一次读取到的时间戳和数据,首次的第一行数据
                            if (flag == 0)
                            {
                                temp = theDate;
                                road_Test.dateTime = theDateSave;
                                arrayRSSI.Add(rssi);
                                road_Test.RSSI = rssi;
                                arraySNR.Add(snr);
                                road_Test.SNR = snr;
                                arrayBLER0Count.Add(bler0count);
                                arrayBLER1Count.Add(bler1count);
                                arrayBLER2Count.Add(bler2count);
                                arrayBLER0.Add(bler0);
                                arrayBLER1.Add(bler1);
                                arrayBLER2.Add(bler2);
                                tempbler2count = bler2count;
                                road_Test.BLER0 = bler0;
                                tempbler1count = bler1count;
                                road_Test.BLER1 = bler1;
                                tempbler0count = bler0count;
                                road_Test.BLER2 = bler2;
                            }
                            else
                            {
                                lock (obj)
                                {
                                    // 计算时间间隔
                                    TimeSpan t1 = new TimeSpan(theDate.Ticks);
                                    TimeSpan t2 = new TimeSpan(temp.Ticks);
                                    TimeSpan ts = t1.Subtract(t2).Duration();
                                    // 在时间间隔内
                                    if (ts.Seconds < period)
                                    {
                                        // Case5
                                        if (checkBox_case.Checked == true)
                                        {
                                            // 处理LDPC总数增长判断为数据正常，不增长的为初始化状态
                                            if (bler0count - tempbler0count < 13.6)
                                            {
                                                // 失锁，标记大红
                                                losinglock0 = true;
                                            }
                                            else
                                            {
                                                arrayBLER0.Add(bler0);
                                                arrayBLER0Count.Add(bler0count);
                                            }
                                            if (bler1count - tempbler1count < 13.6)
                                            {
                                                // 失锁，标记大红
                                                losinglock1 = true;
                                            }
                                            else
                                            {
                                                arrayBLER1.Add(bler1);
                                                arrayBLER1Count.Add(bler1count);
                                            }
                                            if (bler2count - tempbler2count < 35.5)
                                            {
                                                // 失锁，标记大红
                                                losinglock2 = true;
                                            }
                                            else
                                            {
                                                arrayBLER2.Add(bler2);
                                                arrayBLER2Count.Add(bler2count);
                                            }
                                        }
                                        else // Case22
                                        {
                                            // 处理LDPC总数增长判断为数据正常，不增长的为初始化状态
                                            if (bler0count - tempbler0count < 30)
                                            {
                                                // 失锁，标记大红
                                                losinglock0 = true;
                                            }
                                            else
                                            {
                                                arrayBLER0.Add(bler0);
                                                arrayBLER0Count.Add(bler0count);
                                            }
                                            if (bler1count - tempbler1count < 27.5)
                                            {
                                                // 失锁，标记大红
                                                losinglock1 = true;
                                            }
                                            else
                                            {
                                                arrayBLER1.Add(bler1);
                                                arrayBLER1Count.Add(bler1count);
                                            }
                                            if (bler2count - tempbler2count < 27.5)
                                            {
                                                // 失锁，标记大红
                                                losinglock2 = true;
                                            }
                                            else
                                            {
                                                arrayBLER2.Add(bler2);
                                                arrayBLER2Count.Add(bler2count);
                                            }
                                        }
                                        /*
                                        arrayBLER0.Add(bler0);
                                        arrayBLER0Count.Add(bler0count);
                                        arrayBLER1.Add(bler1);
                                        arrayBLER1Count.Add(bler1count);
                                        arrayBLER2.Add(bler2);
                                        arrayBLER2Count.Add(bler2count);
                                        */
                                        arrayRSSI.Add(rssi);
                                        arraySNR.Add(snr);
                                    }
                                    else // 到达统计周期,这统计周期内的数据收集完毕
                                    {
                                        /*
                                        // 计算RSSI的平均数据
                                        int sumrssi = 0;
                                        for (int i = 0; i < arrayRSSI.Count; i++)
                                        {
                                            sumrssi += arrayRSSI[i];
                                        }
                                        int averagerssi = sumrssi / arrayRSSI.Count;
                                        // 计算SNR的平均数据
                                        float sumsnr = 0;
                                        for (int i = 0; i < arraySNR.Count; i++)
                                        {
                                            sumsnr += arraySNR[i];
                                        }
                                        */
                                        double perbler0 = 0.0d;
                                        double perbler1 = 0.0d;
                                        double perbler2 = 0.0d;
                                        // 未失锁
                                        if (!losinglock0)
                                        {
                                            // 计算百分比
                                            int blercount = bler0count - arrayBLER0Count[0];
                                            int bler = bler0 - arrayBLER0[0];
                                            if (bler == 0)
                                            {
                                                perbler0 = 0;
                                            }
                                            else
                                            {
                                                perbler0 = Convert.ToDouble(bler) / Convert.ToDouble(blercount);
                                                perbler0 = Math.Round(perbler0, 4);
                                            }
                                        }
                                        else
                                        {
                                            perbler0 = 1;
                                        }
                                        if (!losinglock1)
                                        {
                                            int blercount = bler1count - arrayBLER1Count[0];
                                            int bler = bler1 - arrayBLER1[0];
                                            if (bler == 0)
                                            {
                                                perbler1 = 0;
                                            }
                                            else
                                            {
                                                perbler1 = Convert.ToDouble(bler) / Convert.ToDouble(blercount); // 得到一个doubler类型的数据
                                                perbler1 = Math.Round(perbler1, 4); // 保留小数点后4位，四舍五入
                                            }
                                        }
                                        else
                                        {
                                            perbler1 = 1;
                                        }
                                        if (!losinglock2)
                                        {
                                            int blercount = bler2count - arrayBLER2Count[0];
                                            int bler = bler2 - arrayBLER2[0];
                                            if (bler == 0)
                                            {
                                                perbler2 = 0;
                                            }
                                            else
                                            {
                                                perbler2 = Convert.ToDouble(bler) / Convert.ToDouble(blercount);
                                                perbler2 = Math.Round(perbler2, 4);
                                            }
                                        }
                                        else  // 失锁
                                        {
                                            perbler2 = 1;
                                        }
                                        // ****************************
                                        // 计算差值,根据统计周期计算数据
                                        // SNR和POW取最大值
                                        // BLER取出错块数和总块数的除计算百分比
                                        // ****************************
                                        road_Test.dateTime = theDateSave;
                                        road_Test.RSSI = arrayRSSI.Max();
                                        // road_Test.SNR = arraySNR.Max();
                                        road_Test.SNR = Math.Round(WeightMean(arraySNR), 1);
                                        road_Test.BLER0 = perbler0;
                                        road_Test.BLER1 = perbler1;
                                        road_Test.BLER2 = perbler2;
                                        try
                                        {
                                            blockingCollectionRoadTest.Add(road_Test);
                                        }
                                        catch (InvalidOperationException invalidex)
                                        {
                                            // GPS数据处理完毕
                                            // Console.WriteLine("GPS数据处理完毕,而路测文件还没处理完毕");
                                            break;
                                        }
                                        /*
                                        Console.WriteLine($"路测时间:{road_Test.dateTime.ToString("yyyy-MM-dd HH:mm:ss")}," +
                                            $"RSSI:{road_Test.RSSI},SNR:{road_Test.SNR},LBER:{road_Test.LBER}");
                                        */
                                        // 开始下一次时间检测
                                        // tempbler0 = bler0;
                                        // tempbler1 = bler1;
                                        // tempbler2 = bler2;
                                        arrayRSSI.Clear();
                                        arrayRSSI.Add(rssi);
                                        arraySNR.Clear();
                                        arraySNR.Add(snr);
                                        arrayBLER0.Clear();
                                        arrayBLER0.Add(bler0);
                                        arrayBLER1.Clear();
                                        arrayBLER1.Add(bler1);
                                        arrayBLER2.Clear();
                                        arrayBLER2.Add(bler2);
                                        arrayBLER0Count.Clear();
                                        arrayBLER0Count.Add(bler0count);
                                        arrayBLER1Count.Clear();
                                        arrayBLER1Count.Add(bler1count);
                                        arrayBLER2Count.Clear();
                                        arrayBLER2Count.Add(bler1count);
                                        temp = theDate;
                                        losinglock0 = false;
                                        losinglock1 = false;
                                        losinglock2 = false;
                                        log.Info($"保存的时间:{temp}");
                                    }
                                }
                            }
                            tempbler0count = bler0count;
                            tempbler1count = bler1count;
                            tempbler2count = bler2count;
                            str2 = stroad.ReadLine();
                            flag = 1;
                        }
                        // 关闭文件流
                        stroad.Close();
                        // 标记添加完成,不再接受任何添加
                        blockingCollectionRoadTest.CompleteAdding();
                        log.Info("路测文件处理完毕!");
                    });

                    // 任务2处理GPS文件中的数据
                    Task task2 = Task.Factory.StartNew(() => {
                        // gps文件中的数据转换为流
                        StreamReader stgps = new StreamReader(@"tmpGps.txt", Encoding.GetEncoding("gb2312"));
                        // 读取一行数据
                        string str = stgps.ReadLine();
                        // 读取GPS文件中的数据
                        int flagGPS = 0;
                        DateTime dateTimeGPS = new DateTime();
                        // 定位状态
                        string positionStateGPS = "";
                        // 经度
                        double longitudeGPS = 0;
                        // 维度
                        double latitudeGPS = 0;
                        // 速度
                        double speedGPS = 0;
                        // 时间戳
                        DateTime tempDate;
                        while (str != null)
                        {
                            if (str != "")
                            {
                                string[] t = str.Split(',');
                                if (t[1] == "$GPRMC")                   // 要是GPRMC格式的数据才保留
                                {
                                    // Console.WriteLine(str);
                                    GPS_info gpsInfo;
                                    // 取GPS中的准确时间$GPRMC中的第3位数据
                                    // 小时分钟秒钟.毫秒，需要加上8个时区
                                    string time = t[2].Substring(0, t[2].Length - 4);
                                    int hour = int.Parse(time.Substring(0, 2)) + 8;
                                    time = hour.ToString() + time.Substring(2, 4);
                                    // 日月年加上小时:分钟:秒钟
                                    string date = t[10] + time;
                                    // 转换为时间
                                    try
                                    {
                                        tempDate = DateTime.ParseExact(date, "ddMMyyHHmmss", CultureInfo.CurrentCulture);
                                    }
                                    catch (FormatException fex)
                                    {
                                        log.Error($"日期转换出错:{fex.Message},出错数据为:{date},出错时间为:{time}");
                                        str = stgps.ReadLine();
                                        continue;
                                    }
                                    // 定位状态
                                    string gpsPositionState = t[3];
                                    // 经度
                                    if (!double.TryParse(t[6], out double gpsLongitude))
                                    {
                                        gpsLongitude = 0;
                                    }
                                    // 维度
                                    if (!double.TryParse(t[4], out double gpsLatitude))
                                    {
                                        gpsLatitude = 0;
                                    }
                                    // 速度
                                    if (!double.TryParse(t[8], out double gpsSpeed))
                                    {
                                        gpsSpeed = 0;
                                    }
                                    if (flagGPS == 0) // 第一次读取GPS数据
                                    {
                                        dateTimeGPS = tempDate;
                                        positionStateGPS = gpsPositionState;
                                        longitudeGPS = gpsLongitude;
                                        latitudeGPS = gpsLatitude;
                                        speedGPS = gpsSpeed;
                                    }
                                    else
                                    {
                                        // 计算时间间隔
                                        TimeSpan t1 = new TimeSpan(tempDate.Ticks);
                                        TimeSpan t2 = new TimeSpan(dateTimeGPS.Ticks);
                                        TimeSpan ts = t1.Subtract(t2).Duration();
                                        if (ts.Seconds > 0) // 超过1秒
                                        {
                                            gpsInfo.dateTime = dateTimeGPS;
                                            gpsInfo.gpsPositionState = positionStateGPS;
                                            gpsInfo.gpsLongitude = longitudeGPS;
                                            gpsInfo.gpsLatitude = latitudeGPS;
                                            gpsInfo.gpsSpeed = speedGPS;
                                            try
                                            {
                                                blockingCollectionGpsInfo.Add(gpsInfo);
                                            }
                                            catch (InvalidOperationException invalidex)
                                            {
                                                // 路测数据处理完毕
                                                // Console.WriteLine("路测数据处理完毕,而GPS文件还没处理完毕");
                                                break;
                                            }
                                            /*
                                            Console.WriteLine($"GPS时间:{gpsInfo.dateTime.ToString("yyyy-MM-dd HH:mm:ss")}," +
                                                $"GPS定位状态:{gpsInfo.gpsPositionState}, GPS经度:{gpsInfo.gpsLongitude}," +
                                                $"GPS维度:{gpsInfo.gpsLatitude}, GPS速度:{gpsInfo.gpsSpeed}");
                                            */
                                            positionStateGPS = gpsPositionState;
                                            longitudeGPS = gpsLongitude;
                                            latitudeGPS = gpsLatitude;
                                            speedGPS = gpsSpeed;
                                        }
                                    }
                                    dateTimeGPS = tempDate;
                                    flagGPS++;
                                }
                            }
                            str = stgps.ReadLine();
                        }
                        // 关闭文件流
                        stgps.Close();
                        // 标记添加完成，不再接受任何添加
                        blockingCollectionGpsInfo.CompleteAdding();
                        log.Info("GPS文件处理完毕!");
                    });

                    // 写入到文件，文件的命名方式以日期命名
                    string filename = DateTime.Now.ToString("yyyyMMddHHmmss");
                    StreamWriter file = new StreamWriter(filename + ".txt", true);
                    // 序号
                    int serial = 1;
                    // 任务3处理数据合并
                    Task task3 = Task.Factory.StartNew(() =>
                    {
                        // 从路测集合中取出一个数据
                        Road_test tempRoad = new Road_test();
                        try
                        {
                            tempRoad = blockingCollectionRoadTest.Take();
                        }
                        catch (InvalidOperationException iex)
                        {
                            log.Error($"路测数据处理结束!");
                        }
                        // 从GPS集合中取出一个数据
                        GPS_info tempGPS = new GPS_info();
                        try
                        {
                            tempGPS = blockingCollectionGpsInfo.Take();
                        }
                        catch (InvalidOperationException iex)
                        {
                            log.Error($"GPS数据处理结束!");
                        }
                        // Console.WriteLine($"取出的路测数据的时间:{tempRoad.dateTime}, GPS的时间{tempGPS.dateTime}");

                        // 判断是否标记为完成并且为空
                        while (!blockingCollectionRoadTest.IsCompleted)
                        {
                            if (blockingCollectionGpsInfo.IsCompleted)
                            {
                                log.Info("GPS数据集合处理完毕!");
                                break;
                            }
                            // 路测数据中的时间和GPS数据中的时间相等
                            if (tempRoad.dateTime == tempGPS.dateTime)
                            {
                                // 进行数据拼接
                                // 格式:RecordSeq,DateTime,GPSState,GPSPositionState,GPSLongitude,
                                // GPSLatitude,GPSSpeed,CdrState,Power,SNR,LDPCErro,LDPCAddErro,LDPCTotal,
                                // CPTErro,CPTTotal,FrameCount,FrameCountAddFlag,FrameHeadError,
                                // FrameHeadAddErro,SubFrameHeadError,AudioSectionHeadError,AudioUnitError,
                                // AudioUnitAddErro,CICTableCount,CICTableError,AudioState
                                StringBuilder stringBuilderKML = new StringBuilder();
                                stringBuilderKML.Append($"{serial},");
                                stringBuilderKML.Append($"{tempRoad.dateTime.ToString("yyyyMMddHHmmss")},");
                                string GPSState = tempGPS.gpsPositionState == "A" ? "GPS_OK" : "GPS_FAILED";
                                stringBuilderKML.Append(GPSState + ",");
                                stringBuilderKML.Append($"{tempGPS.gpsPositionState},");
                                stringBuilderKML.Append($"{tempGPS.gpsLongitude},");
                                stringBuilderKML.Append($"{tempGPS.gpsLatitude},");
                                stringBuilderKML.Append($"{tempGPS.gpsSpeed},");
                                stringBuilderKML.Append("RECEIVE,");
                                stringBuilderKML.Append($"{ tempRoad.RSSI},");
                                stringBuilderKML.Append($"{tempRoad.SNR},");
                                stringBuilderKML.Append($"{tempRoad.BLER0},");
                                stringBuilderKML.Append($"{tempRoad.BLER1},");
                                stringBuilderKML.Append($"{tempRoad.BLER2},");
                                stringBuilderKML.Append("0,0,0,0,0,0,0,0,0,0,0,R");
                                serial++;
                                try
                                {
                                    tempRoad = blockingCollectionRoadTest.Take();

                                }
                                catch (InvalidOperationException invalidex)
                                {
                                    log.Error($"路测集合:{invalidex.Message}");
                                }
                                try
                                {
                                    tempGPS = blockingCollectionGpsInfo.Take();
                                }
                                catch (InvalidOperationException invalidex)
                                {
                                    log.Error($"GPS集合:{invalidex.Message}");
                                }
                                // 打印查看数据
                                log.Info($"拼接的数据:{stringBuilderKML.ToString()}");
                                file.WriteLine(stringBuilderKML.ToString());
                            }
                            else if (tempRoad.dateTime < tempGPS.dateTime)
                            {
                                try
                                {
                                    tempRoad = blockingCollectionRoadTest.Take();
                                }
                                catch (InvalidOperationException exc)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                try
                                {
                                    tempGPS = blockingCollectionGpsInfo.Take();
                                }
                                catch (InvalidOperationException invalidex)
                                {
                                    break;
                                }
                            }
                        }
                        log.Info("路测数据集合处理完毕!");
                        // 标记数据添加完成
                        blockingCollectionRoadTest.CompleteAdding();
                        blockingCollectionGpsInfo.CompleteAdding();
                        // 清空缓冲区，并使所有缓存数据写入流
                        file.Flush();
                        // 关闭流
                        file.Close();
                        log.Info("路测数据和GPS数据处理完成!");
                        MessageBox.Show("路测数据和GPS数据合并完成!");
                    });
                });
                backgroundWorker.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生错误" + ex.ToString());
            }
        }

        /// <summary>
        /// 比较两行数据的时间差
        /// </summary>
        /// <param name="str"></param>
        /// <param name="str2"></param>
        private string Comparer_time(string str, string str2)
        {
            string _str = System.Text.RegularExpressions.Regex.Replace(str, @"\s+", ",").Trim(); // 将字符串中的空格替换为','
            string _str2 = System.Text.RegularExpressions.Regex.Replace(str2, @"\s+", ",").Trim(); // 将字符串中的空格替换为','
            string[] array1 = _str.Split(',');                       // 以','分割字符串
            string time1 = array1[2].Substring(0, 6);                // 去掉时间格式字符串后三位代表毫秒的数据
            // 加8个时区
            // int hour1 = int.Parse(time1.Substring(0, 2)) + 8;
            // time1 = hour1.ToString() + time1.Substring(2, 4);
            string[] array2 = _str2.Split(',');                      // 以','分割字符串
            string time2 = array2[2].Substring(0, 6);                // 去掉时间格式字符串后三位代表毫秒的数据
            // int hour2 = int.Parse(time2.Substring(0, 2)) + 8;
            // time2 = hour2.ToString() + time2.Substring(2, 4);
            // 维度
            double latitude1 = double.Parse(array1[4]);
            double latitude2 = double.Parse(array2[4]);
            // 经度
            double longitude1 = double.Parse(array1[6]);
            double longitude2 = double.Parse(array2[6]);
            DateTime tempDate1 = new DateTime();
            DateTime tempDate2 = new DateTime();
            // 转换为时间
            try
            {
                tempDate1 = DateTime.ParseExact(time1, "HHmmss", CultureInfo.CurrentCulture);
            }
            catch (FormatException ex)
            {
                log.Error($"日期转换出错:{ex.Message},出错数据为:{time1}");
            }
            try
            {
                tempDate2 = DateTime.ParseExact(time2, "HHmmss", CultureInfo.CurrentCulture);
            }
            catch (FormatException ex)
            {
                log.Error($"日期转换出错:{ex.Message},出错数据为:{time2}");
            }
            // 时间间隔
            TimeSpan t1 = new TimeSpan(tempDate1.Ticks);
            TimeSpan t2 = new TimeSpan(tempDate2.Ticks);
            TimeSpan ts = t1.Subtract(t2).Duration();
            int interval = ts.Seconds;
            string temp = _str;
            if (interval != 1) // 没有丢失数据
            {
                string beging = _str.Substring(0, 21);
                string end = _str.Substring(56);
                // 维度的方差
                double common_longitude = Math.Round(CalcCommonDifference(longitude2, longitude1, interval), 4);
                double common_latitude = Math.Round(CalcCommonDifference(latitude2, latitude1, interval), 4);
                long time_start = GetTimeSpan(tempDate1);
                // 新增字符串
                string new_string = "";
                for (int i = 1; i < interval; i++)
                {
                    long temp_time = time_start + i;
                    DateTime new_time = TimeSpanToDateTime(temp_time);
                    new_string = "\n" + beging + new_time.ToString("HHmmss.fff") + ",A," +
                        (latitude1 + common_latitude * i).ToString() + ",N," +
                        (longitude1 + common_longitude * i).ToString() + end;
                    temp += new_string;
                }
            }
            return temp;
        }

        /// <summary>
        /// DateTime转换为时间戳
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private long GetTimeSpan(DateTime time)
        {
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
            return (long)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// 时间戳转换为DateTime
        /// </summary>
        /// <param name="span"></param>
        /// <returns></returns>
        private DateTime TimeSpanToDateTime(long span)
        {
            DateTime time = DateTime.MinValue;
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
            time = startTime.AddSeconds(span);
            return time;
        }

        /// <summary>
        /// 计算公差
        /// </summary>
        /// <param name="end"></param>
        /// <param name="first"></param>
        /// <returns></returns>
        private double CalcCommonDifference(double end, double first, int num)
        {
            double common = (end - first) / num;
            return common;
        }

        /// <summary>
        /// 返回snr的加权平均
        /// </summary>
        /// <param name="snr"></param>
        /// <returns></returns>
        private double WeightMean(List<float> snr)
        {
            // 定义一个字典
            Dictionary<float, int> _snr_d = new Dictionary<float, int>();
            // 遍历赋值
            foreach (float _snr in snr)
            {
                // 判断字典中是否存在这个key
                if (_snr_d.ContainsKey(_snr)) // 存在,数量加1
                {
                    _snr_d[_snr] = _snr_d[_snr] + 1;
                }
                else // 不存在，赋值1
                {
                    _snr_d.Add(_snr, 1);
                }
            }
            double product = 0.0f;
            // 计算加权平均,遍历字典
            foreach (KeyValuePair<float, int> kvp in _snr_d)
            {
                product += kvp.Key * kvp.Value;
            }
            return product / snr.Count;
        }

        private void test()
        {
            string[] x = new string[] { "南山大队", "福田大队", "罗湖大队", "宝安大队", "指挥处", "大帝科技", "南山大队", "福田大队", "罗湖大队", "宝安大队", "指挥处", "大帝科技" };
            double[] y = new double[] { 541, 574, 345, 854, 684, 257, 541, 574, 345, 854, 684, 257 };
            string[] z = new string[] { "", "", "", "", "", "", "", "", "", "", "", "" };

            string[] a = new string[] { "南山大队", "福田大队", "罗湖大队", "宝安大队", "指挥处", };
            double[] b = new double[] { 541, 574, 345, 854, 257 };

            #region 柱状图

            //标题
            chart1.Titles.Add("柱状图数据分析");
            chart1.Titles[0].ForeColor = Color.White;
            chart1.Titles[0].Font = new Font("微软雅黑", 12f, FontStyle.Regular);
            chart1.Titles[0].Alignment = ContentAlignment.TopCenter;
            chart1.Titles.Add("合计：25414 宗");
            chart1.Titles[1].ForeColor = Color.White;
            chart1.Titles[1].Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            chart1.Titles[1].Alignment = ContentAlignment.TopRight;

            //控件背景
            chart1.BackColor = Color.Transparent;
            //图表区背景
            chart1.ChartAreas[0].BackColor = Color.Transparent;
            chart1.ChartAreas[0].BorderColor = Color.Transparent;
            //X轴标签间距
            chart1.ChartAreas[0].AxisX.Interval = 1;
            chart1.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true;
            chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
            chart1.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 14f, FontStyle.Regular);
            chart1.ChartAreas[0].AxisX.TitleForeColor = Color.White;

            //X坐标轴颜色
            chart1.ChartAreas[0].AxisX.LineColor = ColorTranslator.FromHtml("#38587a"); ;
            chart1.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.White;
            chart1.ChartAreas[0].AxisX.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //X坐标轴标题
            //cht1.ChartAreas[0].AxisX.Title = "数量(宗)";
            //cht1.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            //cht1.ChartAreas[0].AxisX.TitleForeColor = Color.White;
            //cht1.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal;
            //cht1.ChartAreas[0].AxisX.ToolTip = "数量(宗)";
            //X轴网络线条
            chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
            chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            //Y坐标轴颜色
            chart1.ChartAreas[0].AxisY.LineColor = ColorTranslator.FromHtml("#38587a");
            chart1.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.White;
            chart1.ChartAreas[0].AxisY.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //Y坐标轴标题
            chart1.ChartAreas[0].AxisY.Title = "数量(宗)";
            chart1.ChartAreas[0].AxisY.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            chart1.ChartAreas[0].AxisY.TitleForeColor = Color.White;
            chart1.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Rotated270;
            chart1.ChartAreas[0].AxisY.ToolTip = "数量(宗)";
            //Y轴网格线条
            chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
            chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            chart1.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
            chart1.ChartAreas[0].BackGradientStyle = GradientStyle.TopBottom;
            Legend legend = new Legend("legend");
            legend.Title = "legendTitle";

            chart1.Series[0].XValueType = ChartValueType.String;  //设置X轴上的值类型
            chart1.Series[0].Label = "#VAL";                //设置显示X Y的值    
            chart1.Series[0].LabelForeColor = Color.White;
            chart1.Series[0].ToolTip = "#VALX:#VAL";     //鼠标移动到对应点显示数值
            chart1.Series[0].ChartType = SeriesChartType.Column;    //图类型(折线)
            
            chart1.Series[0].Color = Color.Lime;
            chart1.Series[0].LegendText = legend.Name;
            chart1.Series[0].IsValueShownAsLabel = true;
            chart1.Series[0].LabelForeColor = Color.White;
            chart1.Series[0].CustomProperties = "DrawingStyle = Cylinder";
            chart1.Legends.Add(legend);
            chart1.Legends[0].Position.Auto = false;
            
            //绑定数据
            chart1.Series[0].Points.DataBindXY(x, y);
            chart1.Series[0].Points[0].Color = Color.White;
            chart1.Series[0].Palette = ChartColorPalette.Bright;
            #endregion

            
            #region 饼图

            //标题
            cht2.Titles.Add("饼图数据分析");
            cht2.Titles[0].ForeColor = Color.White;
            cht2.Titles[0].Font = new Font("微软雅黑", 12f, FontStyle.Regular);
            cht2.Titles[0].Alignment = ContentAlignment.TopCenter;
            cht2.Titles.Add("合计：25412 宗");
            cht2.Titles[1].ForeColor = Color.White;
            cht2.Titles[1].Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            cht2.Titles[1].Alignment = ContentAlignment.TopRight;

            //控件背景
            cht2.BackColor = Color.Transparent;
            //图表区背景
            cht2.ChartAreas[0].BackColor = Color.Transparent;
            cht2.ChartAreas[0].BorderColor = Color.Transparent;
            //X轴标签间距
            cht2.ChartAreas[0].AxisX.Interval = 1;
            cht2.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true;
            cht2.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
            cht2.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 14f, FontStyle.Regular);
            cht2.ChartAreas[0].AxisX.TitleForeColor = Color.White;

            //X坐标轴颜色
            cht2.ChartAreas[0].AxisX.LineColor = ColorTranslator.FromHtml("#38587a"); ;
            cht2.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.White;
            cht2.ChartAreas[0].AxisX.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //X坐标轴标题
            cht2.ChartAreas[0].AxisX.Title = "数量(宗)";
            cht2.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            cht2.ChartAreas[0].AxisX.TitleForeColor = Color.White;
            cht2.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal;
            cht2.ChartAreas[0].AxisX.ToolTip = "数量(宗)";
            //X轴网络线条
            cht2.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
            cht2.ChartAreas[0].AxisX.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            //Y坐标轴颜色
            cht2.ChartAreas[0].AxisY.LineColor = ColorTranslator.FromHtml("#38587a");
            cht2.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.White;
            cht2.ChartAreas[0].AxisY.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //Y坐标轴标题
            cht2.ChartAreas[0].AxisY.Title = "数量(宗)";
            cht2.ChartAreas[0].AxisY.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            cht2.ChartAreas[0].AxisY.TitleForeColor = Color.White;
            cht2.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Rotated270;
            cht2.ChartAreas[0].AxisY.ToolTip = "数量(宗)";
            //Y轴网格线条
            cht2.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
            cht2.ChartAreas[0].AxisY.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            cht2.ChartAreas[0].AxisY2.LineColor = Color.Transparent;

            //背景渐变
            cht2.ChartAreas[0].BackGradientStyle = GradientStyle.None;

            //图例样式
            Legend legend2 = new Legend("#VALX");
            legend2.Title = "图例";
            legend2.TitleBackColor = Color.Transparent;
            legend2.BackColor = Color.Transparent;
            legend2.TitleForeColor = Color.White;
            legend2.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            legend2.Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            legend2.ForeColor = Color.White;

            cht2.Series[0].XValueType = ChartValueType.String;  //设置X轴上的值类型
            cht2.Series[0].Label = "#VAL";                //设置显示X Y的值    
            cht2.Series[0].LabelForeColor = Color.White;
            cht2.Series[0].ToolTip = "#VALX:#VAL(宗)";     //鼠标移动到对应点显示数值
            cht2.Series[0].ChartType = SeriesChartType.Pie;    //图类型(折线)

            cht2.Series[0].Color = Color.Lime;
            cht2.Series[0].LegendText = legend2.Name;
            cht2.Series[0].IsValueShownAsLabel = true;
            cht2.Series[0].LabelForeColor = Color.White;
            cht2.Series[0].CustomProperties = "DrawingStyle = Cylinder";
            cht2.Series[0].CustomProperties = "PieLabelStyle = Outside";
            cht2.Legends.Add(legend2);
            cht2.Legends[0].Position.Auto = true;
            cht2.Series[0].IsValueShownAsLabel = true;
            //是否显示图例
            cht2.Series[0].IsVisibleInLegend = true;
            cht2.Series[0].ShadowOffset = 0;

            //饼图折线
            cht2.Series[0]["PieLineColor"] = "White";
            //绑定数据
            cht2.Series[0].Points.DataBindXY(x, y);
            cht2.Series[0].Points[0].Color = Color.White;
            //绑定颜色
            cht2.Series[0].Palette = ChartColorPalette.BrightPastel;
            #endregion

            /*
            #region Bar图

            //标题
            cht3.Titles.Add("交通违法行为TOP5");
            cht3.Titles[0].ForeColor = Color.White;
            cht3.Titles[0].Font = new Font("微软雅黑", 12f, FontStyle.Regular);
            cht3.Titles[0].Alignment = ContentAlignment.TopCenter;
            cht3.Titles.Add("合计：25412 宗 ");
            cht3.Titles[1].ForeColor = Color.White;
            cht3.Titles[1].Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            cht3.Titles[1].Alignment = ContentAlignment.TopRight;

            //控件背景
            cht3.BackColor = Color.Transparent;
            //图表区背景
            cht3.ChartAreas[0].BackColor = Color.Transparent;
            cht3.ChartAreas[0].BorderColor = Color.Transparent;
            //X轴标签间距
            cht3.ChartAreas[0].AxisX.Interval = 1;
            cht3.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true;
            cht3.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
            cht3.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 14f, FontStyle.Regular);
            cht3.ChartAreas[0].AxisX.TitleForeColor = Color.White;

            //X坐标轴颜色
            cht3.ChartAreas[0].AxisX.LineColor = ColorTranslator.FromHtml("#38587a"); ;
            cht3.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.White;
            cht3.ChartAreas[0].AxisX.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //X坐标轴标题
            //cht3.ChartAreas[0].AxisX.Title = "数量(宗)";
            //cht3.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            //cht3.ChartAreas[0].AxisX.TitleForeColor = Color.White;
            //cht3.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Auto;
            //cht3.ChartAreas[0].AxisX.ToolTip = "数量(宗)";
            //X轴网络线条
            cht3.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
            cht3.ChartAreas[0].AxisX.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            //Y坐标轴颜色
            cht3.ChartAreas[0].AxisY.LineColor = ColorTranslator.FromHtml("#38587a");
            cht3.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.White;
            cht3.ChartAreas[0].AxisY.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //Y坐标轴标题
            //cht3.ChartAreas[0].AxisY.Title = "数量(宗)";
            //cht3.ChartAreas[0].AxisY.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            //cht3.ChartAreas[0].AxisY.TitleForeColor = Color.White;
            //cht3.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Auto;
            //cht3.ChartAreas[0].AxisY.ToolTip = "数量(宗)";
            //Y轴网格线条
            cht3.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
            cht3.ChartAreas[0].AxisY.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            cht3.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
            cht3.ChartAreas[0].AxisX.IsMarginVisible = false;
            cht3.ChartAreas[0].Area3DStyle.Enable3D = true;
            //背景渐变
            cht2.ChartAreas[0].BackGradientStyle = GradientStyle.None;

            //图例样式
            Legend legend3 = new Legend("#VALX");
            legend3.Title = "图例";
            legend3.TitleBackColor = Color.Transparent;
            legend3.BackColor = Color.Transparent;
            legend3.TitleForeColor = Color.White;
            legend3.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            legend3.Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            legend3.ForeColor = Color.White;

            cht3.Series[0].XValueType = ChartValueType.String;  //设置X轴上的值类型
            cht3.Series[0].Label = "#VAL";                //设置显示X Y的值    
            cht3.Series[0].LabelForeColor = Color.White;
            cht3.Series[0].ToolTip = "#VALX:#VAL(宗)";     //鼠标移动到对应点显示数值
            cht3.Series[0].ChartType = SeriesChartType.Bar;    //图类型(折线)

            cht3.Series[0].Color = Color.Lime;
            //cht3.Series[0].LegendText = legend3.Name;
            cht3.Series[0].IsValueShownAsLabel = true;
            cht3.Series[0].LabelForeColor = Color.White;
            cht3.Series[0].CustomProperties = "DrawingStyle = Cylinder";
            cht3.Series[0].CustomProperties = "PieLabelStyle = Outside";
            //cht3.Legends.Add(legend3);
            //cht3.Legends[0].Position.Auto = true;

            //是否显示图例
            cht3.Series[0].IsVisibleInLegend = true;
            cht3.Series[0].ShadowOffset = 0;

            //饼图折线
            cht3.Series[0]["PieLineColor"] = "White";
            //绑定数据
            cht3.Series[0].Points.DataBindXY(a, b);

            //cht3.Series[0].Points[0].Color = Color.White;
            //绑定颜色
            cht3.Series[0].Palette = ChartColorPalette.BrightPastel;

            //for (int n = 0; n < x.Length; n++)
            //{
            //    int ptIdx = cht3.Series[0].Points.AddY(Convert.ToDouble(y[n]));
            //    DataPoint pt = this.cht3.Series[0].Points[ptIdx];
            //    pt.LegendText = x[n] + " " + "#PERCENT{P2}" + " [ " + "#VAL{D} 次" + " ]";//右边标签列显示的文字  
            //    pt.Label = x[n] + " " + "#PERCENT{P2}" + " [ " + "#VAL{D} 次" + " ]"; //圆饼外显示的信息 

            //    //  pt.LabelToolTip = "#PERCENT{P2}";  
            //    //pt.LabelBorderColor = Color.Red;//文字背景色   
            //}





            #endregion


            #region 雷达图

            // //标题
            cht4.Titles.Add("交通违法行为TOP5");
            cht4.Titles[0].ForeColor = Color.White;
            cht4.Titles[0].Font = new Font("微软雅黑", 12f, FontStyle.Regular);
            cht4.Titles[0].Alignment = ContentAlignment.TopCenter;
            cht4.Titles.Add("合计：25412 宗 ");
            cht4.Titles[1].ForeColor = Color.White;
            cht4.Titles[1].Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            cht4.Titles[1].Alignment = ContentAlignment.TopRight;

            //控件背景
            cht4.BackColor = Color.Transparent;
            cht4.ChartAreas[0].BackColor = Color.Transparent;
            cht4.ChartAreas[0].BorderColor = Color.Transparent;
            //X轴标签间距
            cht4.ChartAreas[0].AxisX.Interval = 1;
            cht4.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true;
            cht4.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
            cht4.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 14f, FontStyle.Regular);
            cht4.ChartAreas[0].AxisX.TitleForeColor = Color.White;

            //X坐标轴颜色
            cht4.ChartAreas[0].AxisX.LineColor = ColorTranslator.FromHtml("#38587a"); ;
            cht4.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.White;
            cht4.ChartAreas[0].AxisX.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //X坐标轴标题
            //cht4.ChartAreas[0].AxisX.Title = "数量(宗)";
            //cht4.ChartAreas[0].AxisX.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            //cht4.ChartAreas[0].AxisX.TitleForeColor = Color.White;
            //cht4.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Auto;
            //cht4.ChartAreas[0].AxisX.ToolTip = "数量(宗)";
            //X轴网络线条
            cht4.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
            cht4.ChartAreas[0].AxisX.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            //Y坐标轴颜色
            cht4.ChartAreas[0].AxisY.LineColor = ColorTranslator.FromHtml("#38587a");
            cht4.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.White;
            cht4.ChartAreas[0].AxisY.LabelStyle.Font = new Font("微软雅黑", 10f, FontStyle.Regular);
            //Y坐标轴标题
            //cht4.ChartAreas[0].AxisY.Title = "数量(宗)";
            //cht4.ChartAreas[0].AxisY.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            //cht4.ChartAreas[0].AxisY.TitleForeColor = Color.White;
            //cht4.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Auto;
            //cht4.ChartAreas[0].AxisY.ToolTip = "数量(宗)";
            //Y轴网格线条
            cht4.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
            cht4.ChartAreas[0].AxisY.MajorGrid.LineColor = ColorTranslator.FromHtml("#2c4c6d");

            cht4.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
            cht4.ChartAreas[0].AxisX.IsMarginVisible = false;
            cht4.ChartAreas[0].Area3DStyle.Enable3D = true;
            cht4.ChartAreas[0].AxisX.IsInterlaced = false;
            cht4.ChartAreas[0].AxisX.IsMarginVisible = false;
            //刻度线
            cht4.ChartAreas[0].AxisY.MajorTickMark.Enabled = false;
            //cht4.ChartAreas[0].AxisX.MajorGrid.Enabled = false;
            //cht4.ChartAreas[0].AxisY.MajorGrid.Enabled = false;
            //cht4.ChartAreas[0].AxisX.MajorTickMark.Enabled = false;
            cht4.ChartAreas[0].AxisY.LabelStyle.Enabled = false;
            //背景渐变
            cht4.ChartAreas[0].BackGradientStyle = GradientStyle.None;
            //cht4.ChartAreas[0].AxisX2.InterlacedColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.InterlacedColor = Color.Red;
            //cht4.ChartAreas[0].BorderWidth = 0;
            //cht4.ChartAreas[0].BackSecondaryColor = Color.Red;
            //cht4.ChartAreas[0].BackImageTransparentColor = Color.Red;
            //cht4.ChartAreas[0].AxisX.InterlacedColor = Color.Red;
            //cht4.ChartAreas[0].AxisX.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisX2.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisX2.MajorGrid.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisX2.MajorTickMark.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisX2.MinorTickMark.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisY.InterlacedColor = Color.Red;
            //cht4.ChartAreas[0].AxisY.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.InterlacedColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.MajorGrid.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.MajorTickMark.LineColor = Color.Red;
            //cht4.ChartAreas[0].AxisY2.MinorTickMark.LineColor = Color.Red;


            //图例样式
            Legend legend4 = new Legend();
            legend4.Title = "图例";
            legend4.TitleBackColor = Color.Transparent;
            legend4.BackColor = Color.Transparent;
            legend4.TitleForeColor = Color.White;
            legend4.TitleFont = new Font("微软雅黑", 10f, FontStyle.Regular);
            legend4.Font = new Font("微软雅黑", 8f, FontStyle.Regular);
            legend4.ForeColor = Color.White;
            cht4.Legends.Add(legend4);
            cht4.Legends[0].Position.Auto = true;

            //Series1
            cht4.Series[0].XValueType = ChartValueType.String;
            cht4.Series[0].Label = "#VAL";
            cht4.Series[0].LabelForeColor = Color.White;
            cht4.Series[0].ToolTip = "#LEGENDTEXT:#VAL(宗)";
            cht4.Series[0].ChartType = SeriesChartType.Radar;
            cht4.Series[0]["RadarDrawingStyle"] = "Line";
            cht4.Series[0].LegendText = "2015年";
            cht4.Series[0].IsValueShownAsLabel = true;

            //Series2
            cht4.Series.Add(new Series("Series2"));
            cht4.Series[1].Label = "#VAL";
            cht4.Series[1].LabelForeColor = Color.White;
            cht4.Series[1].ToolTip = "#LEGENDTEXT:#VAL(宗)";
            cht4.Series[1].ChartType = SeriesChartType.Radar;
            cht4.Series[1]["RadarDrawingStyle"] = "Line";
            cht4.Series[1].LegendText = "2016年";
            cht4.Series[1].IsValueShownAsLabel = true;

            //Series3
            cht4.Series.Add(new Series("Series3"));
            cht4.Series[2].Label = "#VAL";
            cht4.Series[2].LabelForeColor = Color.White;
            cht4.Series[2].ToolTip = "#LEGENDTEXT:#VAL(宗)";
            cht4.Series[2].ChartType = SeriesChartType.Radar;
            cht4.Series[2]["RadarDrawingStyle"] = "Line";
            cht4.Series[2].LegendText = "2017年";
            cht4.Series[2].IsValueShownAsLabel = true;


            double[] yValues = { 65.62, 75.54, 60.45, 34.73, 85.42, 55.9, 63.6, 55.2, 77.1 };
            string[] xValues = { "France", "Canada", "Germany", "USA", "Italy", "Spain", "Russia", "Sweden", "Japan" };


            //Seris2  
            double[] y2 = { 45.62, 65.54, 70.45, 84.73, 35.42, 55.9, 63.6 };
            double[] y3 = { 88.62, 35.54, 52.45, 45.73, 88.42, 14.9, 33.6 };
            this.cht4.Series[0].Points.DataBindXY(xValues, yValues);
            this.cht4.Series[1].Points.DataBindY(y2);
            this.cht4.Series[2].Points.DataBindY(y3);


            //设置X轴显示间隔为1,X轴数据比较多的时候比较有用  
            cht4.ChartAreas[0].AxisX.LabelStyle.Interval = 1;
            //设置XY轴标题的名称所在位置位远  
            cht4.ChartAreas[0].AxisX.TitleAlignment = StringAlignment.Near;

            for (int i = 0; i < cht4.Series[2].Points.Count; i++)
            {
                cht4.Series[2].Points[i].MarkerStyle = MarkerStyle.Circle;//设置折点的风格     
                cht4.Series[2].Points[i].MarkerColor = Color.Red;//设置seires中折点的颜色   
                                                                 //    cht4.Series[1].Points[i].MarkerStyle = MarkerStyle.Square;//设置折点的风格     
                                                                 //    cht4.Series[1].Points[i].MarkerColor = Color.Blue;//设置seires中折点的颜色  
                                                                 //    cht4.Series[2].Points[i].MarkerStyle = MarkerStyle.Square;//设置折点的风格     
                                                                 //    cht4.Series[2].Points[i].MarkerColor = Color.Green;//设置seires中折点的颜色  
            }
            for (int i = 0; i < cht4.Series.Count; i++)
            {
                for (int j = 0; j < cht4.Series[i].Points.Count; j++)
                {
                    cht4.Series[i].Points[j].Label = " ";
                    //cht4.Series[i].Points[j].LabelToolTip = "string.Empty";
                }
            }
            //cht4.ImageType = ChartImageType.Jpeg;
            //反锯齿  
            cht4.AntiAliasing = AntiAliasingStyles.All;
            //调色板 磨沙:SemiTransparent  
            cht4.Palette = ChartColorPalette.BrightPastel;

            cht4.Series[0].ChartType = SeriesChartType.Radar;
            cht4.Series[1].ChartType = SeriesChartType.Radar;
            cht4.Series[2].ChartType = SeriesChartType.Radar;
            cht4.Width = 500;
            cht4.Height = 350;

            #endregion
            */
            /* 
                 #VALX      显示当前图例的X轴的对应文本(或数据) 
                 #VAL, #VALY,  显示当前图例的Y轴的对应文本(或数据) 
                 #VALY2, #VALY3, 显示当前图例的辅助Y轴的对应文本(或数据) 
                 #SER:      显示当前图例的名称 
                 #LABEL       显示当前图例的标签文本 
                 #INDEX      显示当前图例的索引 
                 #PERCENT       显示当前图例的所占的百分比 
                 #TOTAL      总数量 
                 #LEGENDTEXT      图例文本 
                 */
        }

        /// <summary>
        /// 隐藏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            this.splitContainer1.Panel2.Hide();
            this.Width = this.splitContainer1.Panel1.Width + 38;
            this.Height = this.splitContainer1.Panel1.Height + 62;
        }

        /// <summary>
        /// 显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            this.splitContainer1.Panel2.Show();
            this.Width = this.splitContainer1.Width;
            this.Height = this.splitContainer1.Height + 62;
        }
    }
}
